﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using System.Web.Security;

namespace TsCore
{
    public class RandomFixture:Fixture
    {

        public RandomFixture()
            :base()
        {
            this.Name = "Fixture llave";
            this.Description = "Genera encuentros en modo de llave. Mínimo 8 equipos, máximo 128";
        }

        //PRE: Minimo 8 Equipos deben participar, Maximo 128 y la cantidad debe ser potencia de 2
        public override List<Match> GenerateMatches(DateTime fromDate, List<Team> teamList)
        {
            List<Match> generatedMatches = new List<Match>();
            try
            {
                if (fromDate.Date <= (DateTime.Now.Date))
                {
                    throw new Exception("El inicio de los Encuentros debe ser mayor a la fecha actual");
                }
                if (ValidTeamCount(teamList.Count))
                {
                    for (int i = 0; i < teamList.Count; i = i + 2)
                    {
                        generatedMatches.Add(new Match(fromDate.AddDays(i / 2), teamList.ElementAt(i), teamList.ElementAt(i + 1)));
                    }
                }

                List<Match> futureMatches = FutureMatches(fromDate.AddDays(teamList.Count / 2), generatedMatches);
                foreach (Match auxMatch in futureMatches)
                {
                    generatedMatches.Add(auxMatch);
                }
            }
            catch (Exception ex)
            {
                LogManager.GetLogger(Membership.GetUser().UserName).Error("Error al generar los Encuentros para un RandomFixture", ex);
            }
            return generatedMatches;
        }

        //Algoritmo recursivo que genera las llaves a futuro.
        private List<Match> FutureMatches(DateTime fromDate, List<Match> matchList)
        {
            List<Match> futureMatches = new List<Match>();
            if (matchList.Count >= 2)
            {
                for (int i = 0; i < matchList.Count; i = i + 2)
                {
                    futureMatches.Add(new Match(fromDate.AddDays(i / 2),
                                        SportHandler.Instance.CreateNewDummyTeam("Ganador: [" + matchList.ElementAt(i).HomeTeam + " vs " + matchList.ElementAt(i).VisitorTeam + "]","~/Sports/Logos/KoalaBB.jpg", new List<Comment>(), matchList.ElementAt(i).HomeTeam.Sport),
                                        SportHandler.Instance.CreateNewDummyTeam("Ganador: [" + matchList.ElementAt(i + 1).HomeTeam + " vs " + matchList.ElementAt(i + 1).HomeTeam + "]","~/Sports/Logos/KoalaBB.jpg", new List<Comment>(), matchList.ElementAt(i).HomeTeam.Sport)
                                        ));
                }

                foreach (Match auxMatch in FutureMatches(fromDate.AddDays(matchList.Count/2), futureMatches))
                {
                    futureMatches.Add(auxMatch);
                }
            }
            return futureMatches;
        }

        private Boolean ValidTeamCount(Int32 teamCount)
        {
            if (teamCount >= 8 && teamCount <= 128)
            {
                if (teamCount == 8 || teamCount == 16 || teamCount == 32 || teamCount == 64 || teamCount == 128)
                {
                    return true;
                }
                else
                {
                    throw new Exception("El numero de equipos debe ser potencia de 2");
                }
            }
            else
            {
                if (teamCount < 8)
                {
                    throw new Exception("Se necesitan al menos 8 equipos");
                }
                else
                {
                    throw new Exception("El maximo de equipos es 128");
                }
            }        
        }
    }
}
